package persistencia;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;

import domain.*;

public class AdministradorPersistenciaLinea {
	private static AdministradorPersistenciaLinea pool;
	private AdministradorPersistenciaNumero administradorPersistenciaNumero;
	private AdministradorPersistenciaPlan administradorPersistenciaPlan;
	private AdministradorPersistenciaUsuario administradorPersistenciaUsuario;
	private AdministradorPersistenciaServicio administradorPersistenciaServicio;
	private AdministradorPersistenciaConsumo administradorPersistenciaConsumo;

	private AdministradorPersistenciaLinea() {
		administradorPersistenciaNumero = AdministradorPersistenciaNumero
				.getInstancia();
		administradorPersistenciaPlan = AdministradorPersistenciaPlan
				.getInstancia();
		administradorPersistenciaUsuario = AdministradorPersistenciaUsuario
				.getInstancia();
		administradorPersistenciaServicio = AdministradorPersistenciaServicio
				.getInstancia();
		administradorPersistenciaConsumo = AdministradorPersistenciaConsumo.getInstancia();
	}

	public static AdministradorPersistenciaLinea getInstancia() {
		if (pool == null)
			pool = new AdministradorPersistenciaLinea();
		return pool;
	}

	public void insert(Linea linea) {
		// Obtener conexion BD
		Connection con = PoolConnection.getPoolConnection().getConnection();

		// Generar sentencia SQL
		try {
			// Preparar sentencia insert en tabla destino
			String senten = "INSERT INTO Lineas (UsuarioId, NumeroId, FechaContrato, PlanId, Estado, Nombre) VALUES (?,?,?,?,?,?)";
			PreparedStatement ps = null;
			ps = con.prepareStatement(senten);
			ps.setInt(1, linea.getUsuario().getId());
			ps.setInt(2, linea.getNumero().getNumeroId());
			ps.setDate(3, new java.sql.Date(linea.getFechaContrato().getTime()));
			ps.setInt(4, linea.getPlan().getId());
			ps.setString(5, linea.getEstado());
			ps.setString(6, linea.getNombre());

			ps.execute();

			PoolConnection.getPoolConnection().realeaseConnection(con);

		} catch (SQLException e) {
			System.out.println("Mensaje Error al Insertar Cliente: "
					+ e.getMessage());
			System.out.println("Stack Trace al Insertar Cliente: "
					+ e.getStackTrace());
			PoolConnection.getPoolConnection().realeaseConnection(con);
		}
	}

	public Vector<Linea> obtenerTodos() {
		Vector<Linea> v = new Vector<Linea>();

		Connection con = PoolConnection.getPoolConnection().getConnection();
		try {

			String senten = "SELECT * from Lineas";
			PreparedStatement ps = null;
			ps = con.prepareStatement(senten);
			ResultSet result = ps.executeQuery();

			while (result.next()) {
				v.add(mapLinea(result));
			}

			PoolConnection.getPoolConnection().realeaseConnection(con);

		} catch (SQLException e) {
			System.out.println("Error al cargar las lineas: "
					+ e.getMessage());			
			PoolConnection.getPoolConnection().realeaseConnection(con);
		}
		return v;
	}

	private Linea mapLinea(ResultSet result) throws SQLException {
		Numero numero = administradorPersistenciaNumero.getNumero(result
				.getInt("NumeroId"));
		Plan plan = administradorPersistenciaPlan.getPlan(result
				.getInt("PlanId"));
		Usuario usuario = administradorPersistenciaUsuario.getUsuario(result
				.getInt("UsuarioId"));

		Linea linea = new Linea(result.getInt("LineaId"), result.getString("Estado"),
				new java.util.Date(result.getDate("FechaContrato").getTime()),
				new java.util.Date(result.getDate("FechaContrato").getTime()),
				numero, plan, usuario, result.getString("Nombre"));
		
		mapConsumosLinea(linea);
		
		return linea;
	}
	
	private void mapConsumosLinea(Linea linea) throws SQLException {
		Connection con = PoolConnection.getPoolConnection().getConnection();
		String senten = "SELECT * from Consumos where LineaId = ?";
		PreparedStatement ps = null;
		ps = con.prepareStatement(senten);
		ps.setInt(1, linea.getId());
		ResultSet result = ps.executeQuery();		

		while (result.next()) {
			Consumo consumo = administradorPersistenciaConsumo.getConsumo(result.getInt("ConsumoId"));			
			linea.addConsumo(consumo);
		}

		PoolConnection.getPoolConnection().realeaseConnection(con);
	}

	public void update(Linea linea) {
		// Obtener conexion BD
		Connection con = PoolConnection.getPoolConnection().getConnection();

		// Generar sentencia SQL
		try {
			// Preparar sentencia insert en tabla destino
			String senten = "UPDATE Lineas set nombre = ? , estado = ?  where LineaId = ?";
			PreparedStatement ps = null;
			ps = con.prepareStatement(senten);
			ps.setString(1, linea.getNombre());
			ps.setString(2, linea.getEstado());
			ps.setInt(3, linea.getId());
			int result = ps.executeUpdate();

			PoolConnection.getPoolConnection().realeaseConnection(con);

		} catch (SQLException e) {
			System.out.println("Mensaje Error al Modificar la Linea: "
					+ e.getMessage());
			System.out.println("Stack Trace al Modificar la Linea "
					+ e.getStackTrace());
			PoolConnection.getPoolConnection().realeaseConnection(con);
		}
		
	}

	public Vector<Linea> obtenerLineasAFacturar() {
		Vector<Linea> v = new Vector<Linea>();

		Connection con = PoolConnection.getPoolConnection().getConnection();
		try {
			
			String senten = "SELECT l.* " +
								"FROM Lineas l " +
								"JOIN Plan p on l.PlanId = p.PlanId "+
								"WHERE p.tipoPlan <> ? AND l.Estado = ?";
			PreparedStatement ps = null;
			ps = con.prepareStatement(senten);
			ps.setString(1, "Prepago");
			ps.setString(2, "Activa");
			ResultSet result = ps.executeQuery();

			while (result.next()) {
				v.add(mapLinea(result));
			}

			PoolConnection.getPoolConnection().realeaseConnection(con);

		} catch (SQLException e) {
			System.out.println("Mensaje Error al Obtener Lineas Facturables: "
					+ e.getMessage());
			System.out.println("Stack Trace al Obtener Lineas Facturables "
					+ e.getStackTrace());
			PoolConnection.getPoolConnection().realeaseConnection(con);
		}
		return v;
	}

}
